package com.wang.ioc;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.wang.ioc.annotation.AnnotationManager;
import com.wang.ioc.annotation.ViewComponent.KeyboardState;
import com.wang.ioc.annotation.ViewComponent.VisibilityState;
import com.wang.ioc.util.ConfigUtils;

public class IocManager {
	public final static int MESSAGE_TYPE_SETDATA=-10000;
	private Map<String,Integer> idMap;
	private static IocManager Instance;
	private IocManager(Context context){
		String packageName=ConfigUtils.getPackageName(context);
		Class idClass=null;
		try {
			idClass=Class.forName(packageName+".R$id");
		} catch (ClassNotFoundException e2) {
			e2.printStackTrace();
		}
		if(idClass==null){
			try {
				ApplicationInfo appInfo = context.getPackageManager()
                        .getApplicationInfo(packageName, PackageManager.GET_META_DATA);
				String ioc_packagename=appInfo.metaData.getString("IOC_PACKAGENAME");
				if(ioc_packagename!=null){
					idClass=Class.forName(ioc_packagename+".R$id");
				}
			} catch (PackageManager.NameNotFoundException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		if(idClass==null){
			return;
		}
		//得到id类的全部属性
		Field[] r_fields=idClass.getDeclaredFields();
		idMap=new HashMap<String,Integer>();
		if(r_fields!=null){
			for(int i=0;i<r_fields.length;i++){
				Field f=r_fields[i];
				String name=f.getName();
				try {
					idMap.put(name, f.getInt(name));
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static IocManager getInstance(Context context){
		if(Instance==null){
			Instance=new IocManager(context);
		}
		return Instance;
	}
	/**
	 * 自动装配view组件。
	 * @param context 上下文对象
	 * @param container 容器对象。
	 * @param viewFinder 获取View实例的对象。
	 * @param listener 事件监听对象。
	 */
	public void autowireView(Context context,Object container,Object viewFinder,Object listener){
		//得到id类的全部属性
		Map<String,Integer> idMap=IocManager.getInstance(context).getIdMap();
		if(idMap==null || idMap.isEmpty()){
			return;
		}
		Field[] fields=container.getClass().getDeclaredFields();
		if(fields!=null){
			for(int i=0;i<fields.length;i++){
				Field f=fields[i];
				//确定该成员变量是否为View类型或其子类。
				Class<?> clazz=f.getType();
				while(!clazz.equals(View.class) && !clazz.equals(Object.class)){
					if(clazz.isInterface() || clazz.getSuperclass()==null){
						break;
					}
					clazz=clazz.getSuperclass();
				}
				//非View则跳过
				if(!clazz.equals(View.class)){
					continue;
				}
				//得到成员变量定义的标注
				Map<String,Object> annoMap=null;
				String name=f.getName();
				int id=0;
				boolean clickEventSource=false;
				String defaultTextValue=null;
				int defaultTextValueResId=0;
				VisibilityState defaultVisibility=VisibilityState.KEEP;
				KeyboardState defaultKeyboardState=KeyboardState.KEEP;
				int parentViewId=0;
				int imageResource=0;
				int backgroundResource=0;
			    int backgroundColor=-1;
			    int backgroundColorResId=0;
				try {
					annoMap=AnnotationManager.loadViewComponentAnnotationVlaue(f);
					if(annoMap!=null){
						if(annoMap.containsKey("isAutowire")){
							//不进行自动装配的view组件将被忽略
							if((Boolean)annoMap.get("isAutowire")==false){
								continue;
							}
						}
						//如果在标注中定义了name属性，则以该属性值作为名称查找，否则默认使用成员变量名。
						if(annoMap.containsKey("name") && !TextUtils.isEmpty((String)annoMap.get("name"))){
							name=(String) annoMap.get("name");
						}
						//获取定义的id
						if(annoMap.containsKey("id")){
							id=(Integer) annoMap.get("id");
						}
						//是否定义有onClick事件监听
						if(annoMap.containsKey("clickEventSource")){
							clickEventSource=(Boolean) annoMap.get("clickEventSource");
						}
						//默认文本内容
						if(annoMap.containsKey("defaultTextValue")){
							defaultTextValue=(String) annoMap.get("defaultTextValue");
						}
						if(annoMap.containsKey("defaultTextValueResId")){
							defaultTextValueResId=(Integer) annoMap.get("defaultTextValueResId");
						}
						//默认是否可见。
						if(annoMap.containsKey("defaultVisibility")){
							defaultVisibility=(VisibilityState) annoMap.get("defaultVisibility");
						}
						//默认是否打开键盘
						if(annoMap.containsKey("defaultKeyboardState")){
							defaultKeyboardState=(KeyboardState) annoMap.get("defaultKeyboardState");
						}
						if(annoMap.containsKey("parentViewId")){
							parentViewId=(Integer) annoMap.get("parentViewId");
						}
						//图像资源id
						if(annoMap.containsKey("imageResource")){
							imageResource=(Integer) annoMap.get("imageResource");
						}
						//背景
						if(annoMap.containsKey("backgroundResource")){
							backgroundResource=(Integer) annoMap.get("backgroundResource");
						}
						if(annoMap.containsKey("backgroundColor")){
							backgroundColor=(Integer) annoMap.get("backgroundColor");
						}
						if(annoMap.containsKey("backgroundColorResId")){
							backgroundColorResId=(Integer) annoMap.get("backgroundColorResId");
						}
						
					}
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				f.setAccessible(true);
				//如果在R类中没有这个id则忽略。
				if(id<=0 && !idMap.containsKey(name)){
					continue;
				}
				//得到父View，用于include多个相同View，实例化多个相同id的组件时进行区分。也应用于键盘的关闭。
				View parentView=null;
				//得到view对象
				View v=null;
				if(viewFinder instanceof Activity){
					parentView=((Activity)viewFinder).findViewById(parentViewId);
					if(parentView==null){
						if(id>0){
							v=((Activity)viewFinder).findViewById(id);
						}
						if(v==null){
							v=((Activity)viewFinder).findViewById(idMap.get(name));
						}
					}else{
						if(id>0){
							v=parentView.findViewById(id);
						}
						if(v==null){
							v=parentView.findViewById(idMap.get(name));
						}
					}
				}else if(viewFinder instanceof View){
					parentView=((View)viewFinder).findViewById(parentViewId);
					View temp=(View)viewFinder;
					if(parentView!=null){
						temp=parentView;
					}
					if(id>0){
						v=temp.findViewById(id);
					}
					if(v==null){
						v=temp.findViewById(idMap.get(name));
					}
				}
				if(v==null){
					continue;
				}
				try {
					f.set(container, v);
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				//处理OnClick监听
				if(clickEventSource && listener!=null){
					try {
						Method mt=clazz.getMethod("setOnClickListener", View.OnClickListener.class);
						if(mt!=null){
							mt.invoke(v, listener);
						}
					} catch (NoSuchMethodException e1) {
						e1.printStackTrace();
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					}
				}
				//处理默认文本内容
				try {
					if(v instanceof TextView){
						if(defaultTextValue!=null && !defaultTextValue.equals("\\@")){
							((TextView) v).setText(defaultTextValue);
						}
						if(defaultTextValueResId!=0){
							((TextView) v).setText(defaultTextValueResId);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				//设置默认是否可见。
				switch(defaultVisibility){
				case KEEP:
					break;
				case VISIBLE:
					v.setVisibility(View.VISIBLE);
					break;
				case GONE:
					v.setVisibility(View.GONE);
					break;
				case INVISIBLE:
					v.setVisibility(View.INVISIBLE);
					break;
				default:
					break;
				}
				//处理默认是否打开键盘
				try {
					if(v instanceof EditText){
						switch(defaultKeyboardState){
						case KEEP:
							break;
						case OPEN:
							v.setFocusable(true);
						    v.setFocusableInTouchMode(true);
						    v.requestFocus();
							break;
						case CLOSE:
							if(parentView!=null){
								parentView.setFocusable(true);
								parentView.setFocusableInTouchMode(true);
							}
							break;
						default:
							break;
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				//处理默认图像资源
				try {
					if(v instanceof ImageView){
						if(imageResource!=0){
							((ImageView) v).setImageResource(imageResource);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				//处理背景
				if(backgroundResource!=0){
					v.setBackgroundResource(backgroundResource);
				}else if(backgroundColor!=-1){
					v.setBackgroundColor(backgroundColor);
				}else if(backgroundColorResId!=0){
					v.setBackgroundColor(context.getResources().getColor(backgroundColorResId));
				}
			}
		}
	}
	/**
	 * 创建初始化时dialog。
	 * @return
	 */
	protected static Dialog createInitingDialog(Context context){
		ProgressDialog progressDialog = ProgressDialog.show(context, "", "请稍候...", true, false);  
        return progressDialog;
	}
	public Map<String,Integer> getIdMap(){
		return idMap;
	}
}
